/*
 *
 * Copyright (C) 2012 Walter Lütgenau
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 */
package offset.nodes.server.servlet.book.epub;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import offset.nodes.Constants;
import offset.nodes.client.model.HttpUtils;
import offset.nodes.server.servlet.book.NameBuilder;
import org.xml.sax.SAXException;

/**
 *
 * @author Walter L�tgenau
 */
public class EpubNameBuilder implements NameBuilder {

   /**
     * Build a name for an image based on the query part of the URL.
     *
     * @param name the URL name
     * @return the name built from the query values.
     * @throws SAXException
     */
    @Override
    public String buildImageName(String name) {
        return buildResourceName(name);
    }

    /**
     * Build a name for an image as referenced in a CSS document based on the
     * query part of the URL.
     *
     * That name must be relative to the document.
     *
     * @param name
     * @return
     */

    @Override
    public String buildCssImageName(String repositoryName) {
        return buildResourceName(repositoryName).substring(EpubBook.RESOURCE_PATH.length());
    }



    /**
     * Return the parameter values of a query as a list of strings.
     *
     * @param url
     * @return
     */
    protected List<String> getParameterValues(String url) {
        ArrayList<String> result = new ArrayList<String>();
        int startQuery = url.indexOf(Constants.QUERY_SEPARATOR);
        if (startQuery < 0)
            return result;

        String query = url.substring(startQuery + 1);
        String[] parameterPairs = query.split(Constants.QUERY_PARAMETER_SEPARATOR);

        for (String parameterPair : parameterPairs) {
            String[] parameterParts = parameterPair.split(Constants.QUERY_ASSIGNEMENT_OPERATOR);
            if (parameterParts.length == 2)
                result.add(parameterParts[1]);
        }

        return result;
    }

    /**
     * Mask a resourceName referring to the epub resources folder.
     *
     * @param name
     * @return
     */
    protected String maskResourceName(String name) {
        if (name.indexOf(Constants.PATH_SEPARATOR) >= 0)
            name = name.substring(name.lastIndexOf(Constants.PATH_SEPARATOR) + 1);
        return EpubBook.RESOURCE_PATH + maskSpecialCharacters(name);
    }

    /**
     * Build a resourceName referring to the epub resources folder.
     *
     * @param name
     * @return
     */
    protected String buildResourceName(String name) {
        int queryStart = name.indexOf(Constants.QUERY_SEPARATOR);
        if (queryStart < 0)
            return maskResourceName(name);

        StringBuffer buf = new StringBuffer();
        Iterator<String> i = getParameterValues(name).iterator();
        while (i.hasNext()) {
            buf.append(i.next());
            if (i.hasNext())
                buf.append("-");
        }

        return maskResourceName(buf.toString());
    }

    /**
     * Mask characters not allowed or useful in the name of a ZIP file
     * 
     * @param name
     * @return
     */
    protected String maskSpecialCharacters(String name) {
        name = name.replaceAll(Constants.PATH_SEPARATOR, "-");
        name = name.replaceAll(" ", "_");
        name = name.replaceAll("%", "");
        name = name.replaceAll(":", "-");
        name = name.replaceAll("\\?", "-");
        name = name.replaceAll("=", "-");
        name = name.replaceAll("&", "-");

        return name;
    }

    @Override
    public String buildStyleSheetName(String repositoryName) {
        return maskResourceName(repositoryName);
    }

    /**
     * Extract the UUID reference from the repository reference.
     * If this does not work, it must have been a path. In this case,
     * discard the leading path separator and substitute other path separators.
     *
     * @param reference
     * @return
     */
    protected String getReference(String reference) {
        URL url;
        try {
            url = new URL(reference);
            if (url.getQuery() != null) {
                HashMap<String, String> parameters = HttpUtils.getParameters(reference);
                if (parameters.get(Constants.PAR_DATA_REFERENCE) != null)
                    return parameters.get(Constants.PAR_DATA_REFERENCE);
                else if (parameters.get(Constants.PAR_NODE_REFERENCE) != null)
                    return parameters.get(Constants.PAR_NODE_REFERENCE);
            } else {
                reference = maskSpecialCharacters(url.getPath());
            }
        } catch (MalformedURLException e) {
            if (reference.startsWith(Constants.PATH_SEPARATOR))
                reference = reference.substring(1);
            reference = maskSpecialCharacters(reference);
        }
        
        return reference;
    }

    public String buildPageName(String repositoryReference) {
        String name = getReference(repositoryReference);
        if (!name.endsWith(".html"))
            name = name + ".html";
        return name;
    }
}
